package com.example.cc.client.refresh;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

/**
 * 配置管理的热加载功能
 */
@Component
@Slf4j
public class DynamicPropertySource {

    private final Map<String, Object> properties = new ConcurrentHashMap<>();
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final ReadLock readLock = rwLock.readLock();
    private final WriteLock writeLock = rwLock.writeLock();

    /**
     * 获取指定键的属性值。
     *
     * @param key 属性键
     * @return 属性值或 null 如果找不到该键
     */
    public Object getProperty(String key) {
        try {
            readLock.lock();
            return properties.get(key);
        } finally {
            readLock.unlock();
        }
    }

    /**
     * 设置或更新指定键的属性值。
     *
     * @param key   属性键
     * @param value 属性值
     */
    public void setProperty(String key, Object value) {
        try {
            writeLock.lock();
            if (value == null) {
                properties.remove(key);
            } else {
                properties.put(key, value);
            }
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 删除指定键的属性。
     *
     * @param key 属性键
     */
    public void deleteProperty(String key) {
        try {
            writeLock.lock();
            properties.remove(key);
            log.info("Deleted property '{}'", key);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 更新多个属性。
     *
     * @param updates 包含要更新的键值对的映射
     */
    public void updateProperties(Map<String, Object> updates) {
        try {
            writeLock.lock();
            updates.forEach((key, value) -> {
                if (value == null) {
                    log.warn("Received null value for key: {}", key);
                    properties.remove(key);
                } else {
                    properties.put(key, value);
                    log.info("Updated property '{}' with value '{}'", key, value);
                }
            });
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 清空所有属性。
     */
    public void clear() {
        try {
            writeLock.lock();
            properties.clear();
            log.info("Cleared all properties");
        } finally {
            writeLock.unlock();
        }
    }
}
